package com.yzcrm.erp.kms.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.yzcrm.common.config.exception.YzcrmException;
import com.yzcrm.common.config.paragetter.BasePageRequest;
import com.yzcrm.common.constant.BaseConstant;
import com.yzcrm.common.lucene.LuceneIndex;
import com.yzcrm.erp.admin.entity.AdminConfig;
import com.yzcrm.erp.admin.entity.AdminField;
import com.yzcrm.erp.admin.entity.AdminScene;
import com.yzcrm.erp.admin.service.AdminFieldService;
import com.yzcrm.erp.admin.service.AdminSceneService;
import com.yzcrm.erp.admin.service.AdminUserService;
import com.yzcrm.erp.crm.common.CrmEnum;
import com.yzcrm.erp.crm.service.CrmRecordService;
import com.yzcrm.erp.kms.entity.KmsCourse;
import com.yzcrm.erp.kms.entity.KmsResource;
import com.yzcrm.erp.kms.entity.KmsResourceFile;
import com.yzcrm.utils.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jiang.xue
 */
public class KmsResourceService {

    @Inject
    private CrmRecordService crmRecordService;

    @Inject
    private AdminFieldService adminFieldService;

    @Inject
    private AdminSceneService adminSceneService;

    @Inject
    private LuceneIndex luceneIndex;


    /**
     * 追加资源
     * @param jsonObject
     * @return
     */
    @Before(Tx.class)
    public R addOrUpdate(JSONObject jsonObject) {

//        Log.getLog(KmsResourceService.class).info(jsonObject.toString() + "....");

        KmsResource kmsResource = jsonObject.getObject("entity", KmsResource.class);
        if(ObjectUtil.isNull(kmsResource)) {
            R.error("参数不正确");
        }
//        Log.getLog(KmsResourceService.class).info(kmsResource + "....");

        // 资源下的文件
        JSONArray jsonArrayFiles = jsonObject.getJSONArray("files");
        if (ObjectUtil.isNull(jsonArrayFiles) || jsonArrayFiles.size() == 0) {
            return R.error("请为该资源添加文件");
        }

        String batchId = StrUtil.isNotEmpty(kmsResource.getBatchId()) ? kmsResource.getBatchId() : IdUtil.simpleUUID();
        if(kmsResource.getResourceId() != null){
            crmRecordService.updateRecord(jsonObject.getJSONArray("field"), batchId);
        }
        adminFieldService.save(jsonObject.getJSONArray("field"), batchId);
        boolean flag;
        if(kmsResource.getResourceId() != null){
            // 更新

            // 资源暂时不用审核
            kmsResource.setCheckStatus(1);
            KmsResource oldKmsResource = new KmsResource().dao().findById(kmsResource.getResourceId());
            crmRecordService.updateRecord(oldKmsResource, kmsResource, CrmEnum.KMS_RESOURCE);
            kmsResource.setUpdateTime(DateUtil.date());
            kmsResource.setUpdateUserId(BaseUtil.getUser().getUserId());
            flag = kmsResource.update();

            // 增加资源下的文件 files
            // 删除后重新加入
            Integer count = Db.update(Db.getSql("kms.resource.deleteFileByResourceId"), kmsResource.getResourceId());
            if (count <= 0) {
                throw new YzcrmException("资源文件添加失败，请刷新页面重新尝试操作");
            }

            // 增加新资源文件
            for (int i = 0; i < jsonArrayFiles.size(); i++) {

                JSONObject jsonObjectFile = jsonArrayFiles.getJSONObject(i);
                KmsResourceFile kmsResourceFile = jsonObjectFile.toJavaObject(KmsResourceFile.class);

                kmsResourceFile.setId(null);
                kmsResourceFile.setResourceId(kmsResource.getResourceId());
                kmsResourceFile.setStatus(1);
                kmsResourceFile.setCreateTime(DateUtil.date());
                kmsResourceFile.setCreateUserId(BaseUtil.getUser().getUserId());
                kmsResourceFile.setUpdateTime(DateUtil.date());
                boolean result = kmsResourceFile.save();
                if(!result) {
                    throw new YzcrmException("资源下的文件保存失败");
                }
            }

            // 更新索引
            luceneIndex.updateContent(BaseConstant.LUCENE_PATH_RESOURCE, CrmEnum.KMS_RESOURCE.getType()+"", kmsResource.getResourceId().toString(), kmsResource.getTitle(), kmsResource.getRemarks());

        }else{
            // 增加
            
            kmsResource.setCreateTime(DateUtil.date());
            kmsResource.setUpdateTime(DateUtil.date());
            kmsResource.setCreateUserId(BaseUtil.getUser().getUserId());
            kmsResource.setBatchId(batchId);
            kmsResource.setCheckStatus(1);// 资源暂时不用审核
            kmsResource.setStatus(1);
            kmsResource.setOwnerUserId(BaseUtil.getUser().getUserId());
            flag = kmsResource.save();
            crmRecordService.addRecord(kmsResource.getResourceId().intValue(), CrmEnum.KMS_RESOURCE);

            // 增加资源下的文件 files
            for (int i = 0; i < jsonArrayFiles.size(); i++) {

                JSONObject jsonObjectFile = jsonArrayFiles.getJSONObject(i);
                KmsResourceFile kmsResourceFile = jsonObjectFile.toJavaObject(KmsResourceFile.class);

                kmsResourceFile.setId(null);
                kmsResourceFile.setResourceId(kmsResource.getResourceId());
                kmsResourceFile.setStatus(1);
                kmsResourceFile.setCreateTime(DateUtil.date());
                kmsResourceFile.setCreateUserId(BaseUtil.getUser().getUserId());
                kmsResourceFile.setUpdateTime(DateUtil.date());
                boolean result = kmsResourceFile.save();
                if(!result) {
                    throw new YzcrmException("资源下的文件保存失败");
                }
            }

            // 创建索引
            luceneIndex.addContent(BaseConstant.LUCENE_PATH_RESOURCE, CrmEnum.KMS_RESOURCE.getType()+"", kmsResource.getResourceId().toString(), kmsResource.getTitle(), kmsResource.getRemarks());

        }

        return flag ? R.ok().put("data", Kv.by("resource_id", kmsResource.getResourceId()).set("remarks", kmsResource.getRemarks())) : R.error();
    }

    /**
     * 获取场景 并 获取资源列表
     * @param basePageRequest
     * @return
     */
    public R filterConditionAndGetPageList(BasePageRequest basePageRequest){

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Integer sceneId = jsonObject.getInteger("sceneId");
        JSONObject data = new JSONObject();
        if(sceneId != null && sceneId != 0){
            data = JSON.parseObject(AdminScene.dao.findById(sceneId).getData());
        }
        if(sceneId == null && jsonObject.getInteger("type") == 1){
            data = new JSONObject().fluentPut("is_transform", new JSONObject().fluentPut("name", "is_transform").fluentPut("condition", "is").fluentPut("value", "0"));
        }
        if(jsonObject.getJSONObject("data") != null){
            if(data != null){
                data.putAll(jsonObject.getJSONObject("data"));
            }
        }
        jsonObject.put("data",data);
        basePageRequest.setJsonObject(jsonObject);
        return getResourcePageList(basePageRequest);
    }

    /**
     * 获取资源列表
     * @param basePageRequest
     * @return
     */
    public R getResourcePageList(BasePageRequest basePageRequest) {

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Kv kv = new Kv();
        List<JSONObject> queryList = new ArrayList<>();
        Integer type = jsonObject.getInteger("type");
        boolean isValid = jsonObject.getBoolean("isValid") != null ? jsonObject.getBoolean("isValid") : false;

        //自定义字段列表
        Map<String, AdminField> fieldMap = adminSceneService.getAdminFieldMap(type);

        // 取得场景名称 同label
        String realm = CrmEnum.parse(type).getName();
        if(ObjectUtil.isNull(realm)) {
            return R.error("type不符合要求");
        }

        // 附加检索条件
        JSONObject data = basePageRequest.getJsonObject().getJSONObject("data");
        if (!adminSceneService.appendSqlCondition(kv, fieldMap, queryList, data, type)){
            return R.error("参数包含非法字段");
        }
        String search = basePageRequest.getJsonObject().getString("search");
        if(StrUtil.isNotEmpty(search)){
            if (!adminSceneService.appendSqlSearch(type, queryList, search)){
                return R.error("参数包含非法字段");
            }
            if(!kv.containsKey("fixed")){
                kv.set("fixed",true);
            }
        }

        // 获取排序字段
        String camelField = basePageRequest.getJsonObject().getString("sortField");
        String sortField = StrUtil.toUnderlineCase(camelField);
        String orderNum = basePageRequest.getJsonObject().getString("order");
        if(StrUtil.isEmpty(sortField) || StrUtil.isEmpty(orderNum)){
            kv.set("orderByKey", "update_time").set("orderByType", "desc").set("fieldType", 1);
        }else{
            if(! ParamsUtil.isValid(sortField)){
                return R.error("参数包含非法字段");
            }
            orderNum = "2".equals(orderNum) ? "asc" : "desc";
            kv.set("orderByKey", sortField).set("orderByType", orderNum).set("fieldType", fieldMap.get(sortField) != null ? fieldMap.get(sortField).getFieldType() : 0);
        }

        // 开始生成条件SQL
        StringBuilder conditions = new StringBuilder();

        //获取已审核数据
        if(isValid) {
            conditions.append(" and check_status = 1");
        }

        conditions.append(" and status != 2");

        // 检索权限
        Long userId = BaseUtil.getUserId();
        List<Integer> roles = BaseUtil.getUser().getRoles();
        if(! BaseConstant.SUPER_ADMIN_USER_ID.equals(userId) && !roles.contains(BaseConstant.SUPER_ADMIN_ROLE_ID)){

            String menuRealm = "resource";

            List<Long> longs = Aop.get(AdminUserService.class).queryUserByAuth(userId, menuRealm);
            if(longs != null && longs.size() > 0){
                conditions.append(" and (a.owner_user_id in (").append(StrUtil.join(",", longs)).append(")");
                conditions.append(")");
            }
        }
        JSONObject sqlObject = new JSONObject();
        sqlObject.put("sql", conditions.toString());
        sqlObject.put("type", 1);
        if(!kv.containsKey("fixed")){
            kv.set("fixed",true);
        }
        queryList.add(sqlObject);

        // 设置分页
        if(StrUtil.isEmpty(basePageRequest.getJsonObject().getString("excel"))){
            kv.set("page", (basePageRequest.getPage() - 1) * basePageRequest.getLimit()).set("limit", basePageRequest.getLimit());
        }

        String selectSql = "select * ";
        List<String> batchList = adminSceneService.queryBatchId(queryList);
        if(batchList.size()==0&&kv.containsKey("field")){
            batchList.add("");
        }
        kv.set("select", selectSql).set("queryList", queryList).set("realm", realm).set("fieldMap", fieldMap).set("label", type);
        kv.set("batchList",batchList);
        SqlPara sqlPara = null;
        if(kv.getInt("fieldType") == 0){
            sqlPara = Db.getSqlPara("kms.resource.queryResourcePageList2", kv);
        }else{
            sqlPara = Db.getSqlPara("kms.resource.queryResourcePageList1", kv);
        }

        // 检索数据
        List<Record> recordPage = Db.find(sqlPara);

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", recordPage);
        SqlPara countSql = Db.getSqlPara("kms.resource.queryResourcePageListCount", kv);
        Integer count = Db.queryInt(countSql.getSql(), countSql.getPara());
        resultJsonObject.put("totalRow", count);
        return R.ok().put("data", resultJsonObject);

    }

    /**
     * 根据资源id查询
     */
    public Record queryById(Integer resourceId){
        Record record = Db.findFirst(Db.getSql("kms.resource.queryById"), resourceId);
        List<Record> recordList = Db.find("select name,value from `yzcrm_admin_fieldv` where batch_id = ?", record.getStr("batch_id"));
        recordList.forEach(field -> record.set(field.getStr("name"), field.getStr("value")));
        return record;
    }

    /**
     * 查询编辑字段
     */
    public List<Record> queryField(Integer resourceId){
        Record resource = queryById(resourceId);
        List<Record> fieldList = adminFieldService.queryUpdateField(CrmEnum.KMS_RESOURCE.getType(), resource);
        return fieldList;
    }

    /**
     * 根据id删除资源
     */
    public R deleteByIds(String customerIds){
        String[] idsArr = customerIds.split(",");
        List<Record> idsList = new ArrayList<>();
        for(String id : idsArr){
            String permissions = "kms:resource:delete";
            if(!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) && !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID)
                    && !AuthUtil.isHavaAuth(permissions)
                    && Db.queryInt(Db.getSql("kms.resource.queryIsOwnerUser"), BaseUtil.getUserId(), id) <= 0){
                return R.error("没有权限");
            }
            Record record = new Record();
            idsList.add(record.set("resource_id", Integer.valueOf(id)));
        }

        List<Record> batchIdList = Db.find(Db.getSqlPara("kms.resource.queryBatchIdByIds", Kv.by("ids", idsArr)));
        boolean result = Db.tx(() -> {
            Db.batchUpdate(Db.getSql("kms.resource.deleteByIds"), "resource_id", idsList, 100);
//            Db.batch("delete from yzcrm_admin_fieldv where batch_id = ?", "batch_id", batchIdList, 100);
            return true;
        });

        if(result == true) {

            for(String id : idsArr) {
                // 删除索引
                luceneIndex.deleteContent(BaseConstant.LUCENE_PATH_RESOURCE, id);
            }
        }

        return result ? R.ok() : R.error();
    }

    /**
     * 基本信息
     */
    public List<Record> information(Integer resourceId) {
        Record record = queryById(resourceId);
        List<String> keyList = Arrays.asList("title", "remarks", "category_id");
        List<Record> recordList = adminFieldService.queryInformation(CrmEnum.KMS_RESOURCE, record, keyList);
        return recordList.stream().sorted(Comparator.comparingInt(r->-r.getInt("field_type"))).map(r-> r.remove("field_type","field_name","setting","type")).collect(Collectors.toList());
    }


    /**
     * 根据资源ID获取资源下的文件
     * @param resourceId
     * @return
     */
    public List<Record> listFilesByResourceId(Integer resourceId) {

        // 根据资源ID获取资源下的文件
        List<Record> listResourceFiles = Db.find(Db.getSql("kms.resource.queryFilesByResourceId"), resourceId);

        return listResourceFiles;
    }

    /**
     * 	获取资源类型
     */
    public R queryResourceCategoryOptions(){

//        List<Record> result = new ArrayList<>();

        List<String> list = Db.query("select value from yzcrm_admin_config where modular_type = 'kms_resource_category'");
//        list.forEach(field -> {
//
//            Record record = new Record();
//
//            record.set(field.getStr("name"), field.getStr("value"));
//
//            result.add(record);
//        });
        return R.ok().put("data", list);
    }

    /**
     *	 设置资源类型
     */
    @Before(Tx.class)
    public R setResourceCategoryOptions(List<String> list){
        Db.delete("delete from yzcrm_admin_config where modular_type = 'kms_resource_category'");
        for(int i = 0; i < list.size(); i++){
            AdminConfig adminConfig = new AdminConfig();
            adminConfig.setModularType("kms_resource_category");
            adminConfig.setName(i+1+"");
            adminConfig.setValue(list.get(i));
            adminConfig.setDescription("学习资源类型");
            adminConfig.save();
        }
        return R.ok();
    }


    /**
     * 获取手机端资源文件列表
     */
    public R getUserResourceList(Integer courseId) {

        // 需要验证是否是本人的课程
        // 检索课程
        KmsCourse course = KmsCourse.dao.findFirst("select * from `yzcrm_kms_course` where `course_id` = ? and status=1",courseId);
        if (ObjectUtil.isNull(course)) {
            throw new YzcrmException("课程不存在");
        }
        // 检索用户拥有的角色
        boolean isOwener = false;
        List<Integer> roles = BaseUtil.getUser().getRoles();
        for (int i = 0; i < roles.size(); i++) {
            String roleId = String.valueOf(roles.get(i));

            String[] arr = course.getRoleId().split(",");
            List<String> list = Arrays.asList(arr);
            if(list.contains(roleId)) {

                isOwener = true;
                break;
            }
        }
        if (!isOwener) {
            throw new YzcrmException("非本人课程无法学习");
        }

        // 检索课程
        List<Record> listCourse = this.queryCourseList(BaseUtil.getUserId(), courseId);

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", listCourse);
        resultJsonObject.put("totalRow", listCourse.size());
        resultJsonObject.put("course", course);

        return R.ok().put("data", resultJsonObject);
    }

    /**
     * 获取手机端资源文件列表
     */
    public R queryPageListByResourceId(Integer paramResourceId) {

        // 检索资源
        KmsResource resource = KmsResource.dao.findFirst("select * from `yzcrm_kms_resource` where `resource_id` = ? and status=1",paramResourceId);
        if (ObjectUtil.isNull(resource)) {
            throw new YzcrmException("资源不存在");
        }

        // 需要验证是否是本人的课程
        List<KmsCourse> listCourseByResourceId = KmsCourse.dao.find(Db.getSql("kms.resource.queryCoursePageListByResourceId"),paramResourceId);
        if (ObjectUtil.isNull(listCourseByResourceId) || listCourseByResourceId.size() <= 0) {
            throw new YzcrmException("课程不存在");
        }

        // 检索用户拥有的角色
        KmsCourse course = null;
        boolean isOwener = false;
        List<Integer> roles = BaseUtil.getUser().getRoles();
        for (int i = 0; i < listCourseByResourceId.size(); i++) {

            course = listCourseByResourceId.get(i);

            for (int j = 0; j < roles.size(); j++) {
                String roleId = String.valueOf(roles.get(j));

                String[] arr = course.getRoleId().split(",");
                List<String> list = Arrays.asList(arr);
                if(list.contains(roleId)) {

                    isOwener = true;
                    break;
                }
            }

            if (isOwener) {
                break;
            }
        }

        if (!isOwener) {
            throw new YzcrmException("非本人课程无法学习");
        }

        Integer courseId = course.getCourseId().intValue();

        // 检索课程
        List<Record> listCourse = this.queryCourseList(BaseUtil.getUserId(), courseId);

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", listCourse);
        resultJsonObject.put("totalRow", listCourse.size());
        resultJsonObject.put("course", course);

        return R.ok().put("data", resultJsonObject);
    }


    /**
     * 获取手机端资源文件列表
     */
    public R queryPageListByFileId(Integer paramFileId) {

        // 检索资源
        KmsResource file = KmsResource.dao.findFirst("select * from `yzcrm_kms_file` where `file_id` = ? and status=1",paramFileId);
        if (ObjectUtil.isNull(file)) {
            throw new YzcrmException("文件不存在");
        }

        // 需要验证是否是本人的课程
        List<KmsCourse> listCourseByFileId = KmsCourse.dao.find(Db.getSql("kms.resource.queryCoursePageListByFileId"),paramFileId);
        if (ObjectUtil.isNull(listCourseByFileId) || listCourseByFileId.size() <= 0) {
            throw new YzcrmException("课程不存在");
        }

        // 检索用户拥有的角色
        KmsCourse course = null;
        boolean isOwener = false;
        List<Integer> roles = BaseUtil.getUser().getRoles();
        for (int i = 0; i < listCourseByFileId.size(); i++) {

            course = listCourseByFileId.get(i);

            for (int j = 0; j < roles.size(); j++) {
                String roleId = String.valueOf(roles.get(j));

                String[] arr = course.getRoleId().split(",");
                List<String> list = Arrays.asList(arr);
                if(list.contains(roleId)) {

                    isOwener = true;
                    break;
                }
            }

            if (isOwener) {
                break;
            }
        }

        if (!isOwener) {
            throw new YzcrmException("非本人课程无法学习");
        }

        Integer courseId = course.getCourseId().intValue();

        // 检索课程
        List<Record> listCourse = this.queryCourseList(BaseUtil.getUserId(), courseId);

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", listCourse);
        resultJsonObject.put("totalRow", listCourse.size());
        resultJsonObject.put("course", course);

        return R.ok().put("data", resultJsonObject);
    }


    private List<Record> queryCourseList(Long userId, Integer courseId) {

        Kv kv = new Kv();
        kv.set("userId", userId);
        kv.set("courseId", courseId);

        // 检索资源
        SqlPara sqlPara = Db.getSqlPara("kms.course.queryUserCourseResourceList", kv);
        List<Record> listCourse = Db.find(sqlPara);
        listCourse.forEach(record->{

            Long resourceId = record.get("resource_id");

            kv.set("resourceId", resourceId);

            // 检索资源下的文件
            SqlPara sqlPara2 = Db.getSqlPara("kms.resource.queryUserResourceFileListByResourceId", kv);
            List<Record> listFile = Db.find(sqlPara2);
            listFile.forEach(file->{

                String path = file.getStr("path");
                String url = FileUploadUtil.getPreviewURL(path);
                file.set("url", url);
            });
            record.set("files", listFile);

        });

        return listCourse;
    }

}
